import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.image.*;
import java.util.ArrayList;
import java.util.Random;
import java.awt.event.*;

class Ball {
    int x, y, dx, dy, d;
    
    Ball(int x, int y, int dx, int dy, int d)
    {
        this.x = x;
        this.y = y;
        this.dx = dx;
        this.dy = dy;
        this.d = d;
    }
}

class MyPanel extends JPanel {
    static final int SIZ = 32, A = 8;
    ArrayList<Ball> balls = new ArrayList<>();
    boolean gameStarted = false;
    
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        for (Ball ball : balls) {
            g.fillOval(ball.x, ball.y, ball.d, ball.d);
        }
    }
    
    MyPanel()
    {
        BufferedImage bi = new BufferedImage(SIZ, SIZ, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.getGraphics();
        g.setColor(Color.YELLOW);
        g.fillRect(0, 0, A, A);
        setCursor(Toolkit.getDefaultToolkit().createCustomCursor(bi, new Point(0, 0), ""));
    }
    
    void updateBallPos()
    {
        if (gameStarted) {
            Point mousePos = getMousePosition();
            if (mousePos != null) {
                for (Ball ball : balls) {
                    if (Math.hypot(ball.x + ball.d / 2. - (mousePos.x + A / 2.), ball.y + ball.d / 2. - (mousePos.y + A / 2.)) <= ball.d / 2.) {
                        JOptionPane.showMessageDialog(null, "Game Over", "提示", JOptionPane.ERROR_MESSAGE);
                        gameStarted = false;
                        break;
                    }
                    
                    ball.x += ball.dx;
                    ball.y += ball.dy;
                    if (ball.x < 0 || ball.x >= getWidth() - ball.d) {
                        ball.dx = -ball.dx;
                    }
                    if (ball.y < 0 || ball.y >= getHeight() - ball.d) {
                        ball.dy = -ball.dy;
                    }
                }
            }
        }
        repaint();
    }
}

public class Frame extends JFrame {
    private static final long serialVersionUID = 1L;
    private MyPanel pnlBall;
    private final Timer timer = new Timer(0, new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            pnlBall.updateBallPos();
            if (!pnlBall.gameStarted) {
                timer.stop();
            }
        }
    });
    
    /**
     * Launch the application.
     */
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable() {
            public void run()
            {
                try {
                    Frame frame = new Frame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    
    /**
     * Create the frame.
     */
    JPanel pnl;
    int cnt = 1;
    
    public Frame()
    {
        timer.setDelay(1);
        setTitle("弹球游戏 222200428_黄铎彦 保留所有权利");
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(0, 0, 450, 300);
        
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        JMenuItem nemuNew = new JMenuItem("新游戏");
        nemuNew.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                pnlBall.gameStarted = false;
                while (true) {
                    try {
                        String inpt = JOptionPane.showInputDialog("输入小球个数", cnt);
                        if (inpt == null) {
                            break;
                        }
                        int t = Integer.parseInt(inpt);
                        if (t <= 0) {
                            throw new IllegalArgumentException();
                        }
                        pnlBall.gameStarted = true;
                        timer.start();
                        cnt = t;
                        pnlBall.balls.clear();
                        Random rand = new Random();
                        for (int i = 0; i < cnt; i++) {
                            int x = rand.nextInt(pnlBall.getWidth());
                            int y = rand.nextInt(pnlBall.getHeight());
                            int dx = rand.nextInt(3) - 1;
                            int dy = rand.nextInt(3) - 1;
                            int d = 10;
                            pnlBall.balls.add(new Ball(x, y, dx, dy, d));
                        }
                        break;
                    } catch (Exception ex) {
                        JOptionPane.showMessageDialog(null, "输入的不是正整数，请重新输入！", "错误", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }
        });
        menuBar.add(nemuNew);
        
        JMenuItem menuAbout = new JMenuItem("关于");
        menuAbout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                JOptionPane.showMessageDialog(null, "黄铎彦提醒你：新质生产力的船即将启航，请抓紧时间买票上船！", "关于", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        menuBar.add(menuAbout);
        
        pnlBall = new MyPanel();
        pnlBall.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseExited(MouseEvent e)
            {
                if (pnlBall.gameStarted) { // 只有在游戏开始后，才显示游戏结束的提示
                    pnlBall.gameStarted = false;
                    JOptionPane.showMessageDialog(null, "Game Over", "提示", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        pnl = new JPanel();
        setContentPane(pnl);
        pnl.setLayout(new BorderLayout(0, 0));
        pnl.add(pnlBall, BorderLayout.CENTER);
    }
}